<template>
  <div class="frame" :style="{paddingLeft, paddingTop}">
    <!-- 左侧菜单 -->
    <menu-left ref="menuLeft" @topBarCollapse="topBarCollapse" />

    <!-- 顶栏、选项卡 -->
    <top-bar :menuOpen="menuOpen" @click="visibleMenu" @personalityShow="personalityShow">
      <work-tab v-if="showWorkTab" />
    </top-bar>

    <!-- 内容区 -->
    <div class="container">
      <keep-alive v-if="isRouterAlive">
        <router-view :style="{minHeight}"></router-view>
      </keep-alive>
    </div>

    <!-- 个性化 -->
    <personality
      :show="personalityOpen"
      @click="personalityShow"
      @closePersonality="closePersonality"
    />
  </div>
</template>

<script>
// import _ from 'lodash';
import { menuLeftOpenWidth, menuLeftShrinkWidth } from '@/config/menu';
import { mapState } from 'vuex';

export default {
  provide () {
    return {
      reload: this.reload,
    };
  },
  created () {
    let _this = this;
    _this.sessionTimeOut = setInterval(() => {
      _this.timeOut = Number(localStorage.getItem('SYSTEM.SESSION.TIMEOUT'));
      _this.timeOut--;
      localStorage.setItem('SYSTEM.SESSION.TIMEOUT', _this.timeOut);
    }, 1000);
  },
  data () {
    return {
      // 菜单是否展开
      menuOpen: true,
      // KeepAlive
      isRouterAlive: true,
      // 个性化可见性
      personalityOpen: false,
      // 显示多标签
      showWorkTab: true,
      // 全局定时器
      timeOut: null,
      sessionTimeOut: null
    };
  },
  computed: {
    ...mapState({
      setting: state => state.setting.setting
    }),
    paddingLeft () {
      let width = this.menuOpen ? menuLeftOpenWidth : menuLeftShrinkWidth;
      this.$store.dispatch('menu/setMenuWidth', width);
      return width;
    },
    paddingTop () {
      return this.showWorkTab ? '108px' : '75px';
    },
    minHeight () {
      return `calc(100vh - ${this.showWorkTab ? '120px' : '90px'})`;
    }
  },
  watch: {
    'setting.showWorkTab': {
      handler (show) {
        this.showWorkTab = show;
      },
      immediate: true
    },
    timeOut: {
      handler (val) {
        let _this = this;
        if (val === 0) {
          localStorage.clear();
          _this.$http.get({ url: '/action/logout' });
          document.getElementsByTagName('html')[0].removeAttribute('class'); // 移除暗黑主题
          _this.$store.dispatch('user/setLoginStatus', false);
          _this.$message.error('会话超时，请重新登录！');
          _this.$router.push('/login');
        }
      },
      immediate: true
    }
  },
  mounted () {
    let _this = this;
    _this.initWebSocket();
    _this.refreshSaveUserData();
    _this.$nextTick(() => {
      // 订阅服务端-微服务上、下线消息
      _this.$ws.registerDgQueueListener('uap.system.nodes', _this.dealStart);
    });
  },
  // 销毁
  beforeDestroy () {
    let _this = this;
    // 执行销毁
    clearInterval(_this.sessionTimeOut);
    _this.$ws.unregisterDgQueueListener(_this.dealStart);
  },
  destroyed () {
    // 断开websocket连接
    this.$ws.disconnect();
  },
  methods: {
    // 服务端 - 微服务上、下线
    dealStart (data) {
      let _this = this;
      if (data && data.payload) {
        let result = data.payload;
        // let apps = _.chain(result.apps).map(it => it.toUpperCase()).join(',').value();
        if (result.type !== 'online') {
          _this.$notify.error({
            title: '服务进程异常！',
            message: '关联服务已下线,被强制退出,请联系服务器管理人员!',
          });
          localStorage.clear();
          this.$http.get({ url: '/action/logout' });
          document.getElementsByTagName('html')[0].removeAttribute('class'); // 移除暗黑主题
          this.$store.dispatch('user/setLoginStatus', false);
          this.$router.push('/login');
        }
      }
    },
    // 连接websocket
    async initWebSocket () {
      let _this = this;
      await _this.$ws.connect();
      const sessionId = await _this.$http.get({ url: '/api/gateway/stompqueue' });
      await Promise.all([_this.$ws.subscribeUserMessage(sessionId), _this.$ws.subscribeDomainMessage(sessionId)]);
    },
    // Vuex中的数据保存到localStorage，在即将离开当前页面(刷新或关闭)时执行
    refreshSaveUserData () {
      let _this = this;
      window.addEventListener('beforeunload', () => {
        _this.$store.dispatch('user/storeStorage');
      });
    },
    // 刷新页面
    reload () {
      this.isRouterAlive = false;
      this.$nextTick(function() {
        this.isRouterAlive = true;
      });
    },
    // 菜单展开 | 收缩
    visibleMenu () {
      this.menuOpen = !this.menuOpen;
      this.$refs.menuLeft.visibleMenu();
    },
    topBarCollapse (show) {
      this.menuOpen = show;
    },
    personalityShow () {
      this.personalityOpen = !this.personalityOpen;
    },
    closePersonality () {
      this.personalityOpen = false;
    }
  }
};
</script>

<style lang="scss" scoped>
.frame {
  width: 100%;
  min-height: 100vh;
  padding: 108px 0 15px 0;
  box-sizing: border-box;
  transition: padding 0.3s ease-in-out;
  background: $default-background;
  overflow: hidden;

  .container {
    width: calc(100% - 30px);
    min-height: 100%;
    margin: auto;
    box-sizing: border-box;

    // 子页面默认style
    ::v-deep .page-content {
      background: #fff;
      padding: 16px;
      position: relative;
      box-sizing: border-box;
      border-radius: 3px;

      ::v-deep .open-head-btn {
        width: 100%;
        height: 15px;
        cursor: pointer;
        user-select: none;
        -moz-user-select: none;
        -webkit-user-select: none;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        margin: auto;
        z-index: 999;
        text-align: center;
        font-size: 12px;
        color: #eee;
      }
    }
  }
}

@media only screen and (max-width: $device-ipad) {
  .frame {
    width: 100%;
    padding-left: 0 !important;
    min-height: 100vh;
    overflow-y: scroll;

    .container {
      width: calc(100% - 20px);
    }
  }
}
</style>
